////////////////////////////////////////////////////////////////
//	File	:	"CLevelEngine.h"
//
//	Author	:	James Gonzalez (JG), (Modified) Travis Setz
//
//	Purpose	:	This class loads all the level data for the game
////////////////////////////////////////////////////////////////
#include "CLevelEngine.h"
#include "../Wrappers/CSGD_TextureManager.h"
#include "CObjectManager.h"
#include "CEventSystem.h"
#include "../xml/tinyxml.h"
#include "CPlayer.h"
#include "CPowerUp.h"
#include "CEnemy.h"
#include "CTurret.h"
#include "CGamePlayState.h"
#include "CMessageSystem.h"
#include "CProfileManager.h"

#define LevelXPos 80
#define LevelYPos 70

CLevelEngine::CLevelEngine(void)
{
	SetLevelPosX(LevelXPos);
	SetLevelPosY(LevelYPos);
 	pTM = CSGD_TextureManager::GetInstance();
 
	m_pOM = CObjectManager::GetInstance();
	m_pFactory = CObjectFactory<string, CBase>::GetInstance();
	m_pFactory->RegisterClassType<CEnemy>("CEnemy");
	m_pFactory->RegisterClassType<CPowerUp>("CPowerUp");
	m_pFactory->RegisterClassType<CBlock>("CBlock");
	m_pFactory->RegisterClassType<CPlayer>("CPlayer");
	m_pFactory->RegisterClassType<CTurret>("CTurret");

	m_nAllIamges = pTM->LoadTexture("Resource/BS_All_Images.png");

//  m_nImageID[ERASE] = pTM->LoadTexture("Resource/Tiles/BS_ERASE.bmp");
//  m_nImageID[Start] = pTM->LoadTexture("Resource/Tiles/BS_Start.bmp");
//  m_nImageID[Exit] = pTM->LoadTexture("Resource/Tiles/BS_Exit.bmp");
// 	m_nImageID[Block_All] = pTM->LoadTexture("Resource/Tiles/BS_Block_All.bmp");
// 	m_nImageID[Block_Horizontal] = pTM->LoadTexture("Resource/Tiles/BS_Block_Horizontal.bmp");	
// 	m_nImageID[Block_HorizontalAuto] = pTM->LoadTexture("Resource/Tiles/BS_Block_HorizontalAuto.bmp");
// 	m_nImageID[Block_Static] = pTM->LoadTexture("Resource/Tiles/BS_Block_Static.bmp");
// 	m_nImageID[Block_Vertical] = pTM->LoadTexture("Resource/Tiles/BS_Block_Vertical.bmp");
// 	m_nImageID[Block_VerticalAuto] = pTM->LoadTexture("Resource/Tiles/BS_Block_VerticalAuto.bmp");
// 	m_nImageID[Bomb_Enemy] = pTM->LoadTexture("Resource/Tiles/BS_EnemyBomb.png");
// 	m_nImageID[Bomb_force] = pTM->LoadTexture("Resource/Tiles/BS_FBomb.png");
// 	m_nImageID[Bomb_Regular] = pTM->LoadTexture("Resource/Tiles/BS_RegBomb.png");
// 	m_nImageID[Door_Blue] = pTM->LoadTexture("Resource/Tiles/BS_Door_Blue.bmp");
// 	m_nImageID[Door_Green] = pTM->LoadTexture("Resource/Tiles/BS_Door_Green.bmp");
// 	m_nImageID[Door_Red] = pTM->LoadTexture("Resource/Tiles/BS_Door_Red.bmp");
// 	m_nImageID[Door_Yellow] = pTM->LoadTexture("Resource/Tiles/BS_Door_Yellow.bmp");
// 	m_nImageID[Key_Blue] = pTM->LoadTexture("Resource/Tiles/BS_Key_Blue.bmp");
// 	m_nImageID[Key_Green] = pTM->LoadTexture("Resource/Tiles/BS_Key_Green.bmp");
// 	m_nImageID[Key_Red] = pTM->LoadTexture("Resource/Tiles/BS_Key_Red.bmp");
// 	m_nImageID[Key_Yellow] = pTM->LoadTexture("Resource/Tiles/BS_Key_Yellow.bmp");
// 	m_nImageID[PowerUp_Balloon] = pTM->LoadTexture("Resource/Tiles/BS_PowerUp_Balloon.bmp");
// 	m_nImageID[PowerUp_Brick] = pTM->LoadTexture("Resource/Tiles/BS_PowerUp_Brick.bmp");
// 	m_nImageID[PowerUp_Goo] = pTM->LoadTexture("Resource/Tiles/BS_PowerUp_Goo.bmp");
// 	m_nImageID[PowerUp_MetalBoots] = pTM->LoadTexture("Resource/Tiles/BS_PowerUp_MetalBoots.bmp");
// 	m_nImageID[PowerUp_Mirror] = pTM->LoadTexture("Resource/Tiles/BS_PowerUp_Mirror.bmp");
// 	m_nImageID[PowerUp_Parachute] = pTM->LoadTexture("Resource/Tiles/BS_PowerUp_Parachute.bmp");
// 	m_nImageID[PowerUp_Spring] = pTM->LoadTexture("Resource/Tiles/BS_PowerUp_Spring.bmp");
// 	m_nImageID[Enemy_Simple] = pTM->LoadTexture("Resource/Tiles/BS_Enemy_Simple.bmp");
// 	m_nImageID[Enemy_Jumping] = pTM->LoadTexture("Resource/Tiles/BS_Enemy_Jumping.bmp");
// 	m_nImageID[Enemy_Zombie] = pTM->LoadTexture("Resource/Tiles/BS_Enemy_Zombie.bmp");
// 	m_nImageID[Enemy_Turret] = pTM->LoadTexture("Resource/Tiles/BS_Enemy_Turret.bmp");
// 	m_nImageID[SpikeUp] = pTM->LoadTexture("Resource/Tiles/BS_SpikeUp.bmp");
// 	m_nImageID[SpikeDown] = pTM->LoadTexture("Resource/Tiles/BS_SpikeDown.bmp");
// 	m_nImageID[SpikeLeft] = pTM->LoadTexture("Resource/Tiles/BS_SpikeLeft.bmp");
// 	m_nImageID[SpikeRight] = pTM->LoadTexture("Resource/Tiles/BS_SpikeRight.bmp");
	


}

CLevelEngine::~CLevelEngine(void)
{
}

CLevelEngine* CLevelEngine::GetInstance(void)
{
	static CLevelEngine instance;
	return &instance;
}




bool CLevelEngine::LoadLevel(const char* szFileName)
{

	TiXmlDocument xmlDoc;

	if (!xmlDoc.LoadFile(szFileName))
		return false;
	
	sprintf_s(m_szFileName,"%s",szFileName);

	TiXmlElement* pRoot = xmlDoc.RootElement();
	TiXmlElement* pElement	= pRoot->FirstChildElement("Tile");
	
		
 	for (int i = 0; i < 16; i++)
 	{
 		for (int j = 0; j < 16; j++)
		{
			int ObjectType = 0;
			pElement->Attribute("type",&ObjectType);
			if (ObjectType != ERASE)
			{	
				CreateBlock(ObjectType,i,j);
				CreateTurret(ObjectType,i,j);
				CreatePowerUp(ObjectType,i,j);
				CreateEnemy(ObjectType,i,j);
			}
			pElement = pElement->NextSiblingElement("Tile");

			
 		}
 	}	
	return true;
}

void CLevelEngine::UnloadLoadLevel()
{
	
	m_pOM->RemoveAllObjects();

}


 void CLevelEngine::ReloadLevel()
 {
	
	 if (m_szFileName)
	 {
		 m_pOM->RemoveAllObjects();
		 LoadLevel(m_szFileName); 
		 
		 CGamePlayState::GetInstance()->SetPlayer(NULL);
		 CMessageSystem::GetInstance()->SendMsg(new CCreatePlayerMessage());
		 
	 }
 
 }

 void CLevelEngine::CreateEnemy(int nEnemyType, int nX, int nY)
 {
	 CEnemy* testEnemy = NULL;

	 switch(nEnemyType)
	 {
	 case Enemy_Simple:
		 testEnemy = (CEnemy*)m_pFactory->CreateObject("CEnemy");
		 testEnemy->SetEnemyType(SIMPLE);
		 testEnemy->SetImageIndex(0,2);
		 //testEnemy->SetImageID(m_nImageID[nEnemyType]);
		 break;
	 case Enemy_Jumping:
		 testEnemy = (CEnemy*)m_pFactory->CreateObject("CEnemy");
		 testEnemy->SetEnemyType(JUMPING);
		 testEnemy->SetImageIndex(2,2);
		// testEnemy->SetImageID(m_nImageID[nEnemyType]);
		 testEnemy->SetWeight(170);
		 break;
	 case Enemy_Zombie:
		 testEnemy = (CEnemy*)m_pFactory->CreateObject("CEnemy");
		 testEnemy->SetEnemyType(ZOMBIE);
		 testEnemy->SetImageIndex(1,2);
		 //testEnemy->SetImageID(m_nImageID[nEnemyType]);
		 break;
	 }

	if (testEnemy)
	{
		testEnemy->SetCurrentTheme(CProfileManager::GetInstance()->GetCurrentTheme());
		testEnemy->SetImageID(m_nAllIamges);
		testEnemy->SetHeight(32);
		testEnemy->SetWidth(32);
		testEnemy->SetPosX((float)(LevelXPos+nX*testEnemy->GetWidth()));
		testEnemy->SetPosY((float)(LevelYPos+nY*testEnemy->GetHeight()));
		testEnemy->SetVelY(0);
		testEnemy->SetVelX(0);
		m_pOM->AddObject(testEnemy);  
		testEnemy->Release(); 
	}
 }

 void CLevelEngine::CreatePowerUp(int nPowerUpType, int nX, int nY)
 {
	 CPowerUp * testPowerUp = NULL;

	 switch(nPowerUpType)
	 {
	 case Bomb_Enemy:
		 testPowerUp = (CPowerUp*)m_pFactory->CreateObject("CPowerUp");
		 testPowerUp->SetPowerUpType(ENEMYAMMO);
		 testPowerUp->SetImageIndex(13,1);
		 //testPowerUp->SetImageID(m_nImageID[nPowerUpType]);
		 break;
	 case Bomb_force:
		 testPowerUp = (CPowerUp*)m_pFactory->CreateObject("CPowerUp");
		 testPowerUp->SetPowerUpType(FORCEAMMO);
		 testPowerUp->SetImageIndex(14,1);
		 //testPowerUp->SetImageID(m_nImageID[nPowerUpType]);
		 break;
	 case Bomb_Regular:
		 testPowerUp = (CPowerUp*)m_pFactory->CreateObject("CPowerUp");
		 testPowerUp->SetPowerUpType(REGULARAMMO);
		 testPowerUp->SetImageIndex(12,1);
		 //testPowerUp->SetImageID(m_nImageID[nPowerUpType]);
		 break;
	 case PowerUp_Balloon:
		 testPowerUp = (CPowerUp*)m_pFactory->CreateObject("CPowerUp");
		 testPowerUp->SetPowerUpType(BALLOON);
		 testPowerUp->SetImageIndex(11,1);
		 //testPowerUp->SetImageID(m_nImageID[nPowerUpType]);
		 break;
	 case PowerUp_Brick:
		 testPowerUp = (CPowerUp*)m_pFactory->CreateObject("CPowerUp");
		 testPowerUp->SetPowerUpType(BRICK);
		 testPowerUp->SetImageIndex(10,1);
		 //testPowerUp->SetImageID(m_nImageID[nPowerUpType]);
		 break;
	 case PowerUp_Goo:
		 testPowerUp = (CPowerUp*)m_pFactory->CreateObject("CPowerUp");
		 testPowerUp->SetPowerUpType(GOO);
		 testPowerUp->SetImageIndex(9,1);
		 //testPowerUp->SetImageID( m_nImageID[nPowerUpType]);
		 break;
	 case PowerUp_MetalBoots:
		 testPowerUp = (CPowerUp*)m_pFactory->CreateObject("CPowerUp");
		 testPowerUp->SetPowerUpType(METAL);
		 testPowerUp->SetImageIndex(8,1);
		 //testPowerUp->SetImageID( m_nImageID[nPowerUpType]);
		 break;
	 case PowerUp_Mirror:
		 testPowerUp = (CPowerUp*)m_pFactory->CreateObject("CPowerUp");
		 testPowerUp->SetPowerUpType(MIRROR);
		 testPowerUp->SetImageIndex(7,1);
		 //testPowerUp->SetImageID( m_nImageID[nPowerUpType]);
		 break;
	 case PowerUp_Parachute:
		 testPowerUp = (CPowerUp*)m_pFactory->CreateObject("CPowerUp");
		 testPowerUp->SetPowerUpType(PARACHUTE);
		 testPowerUp->SetImageIndex(6,1);
		 //testPowerUp->SetImageID( m_nImageID[nPowerUpType]);
		 break;
	 case PowerUp_Spring:
		 testPowerUp = (CPowerUp*)m_pFactory->CreateObject("CPowerUp");
		 testPowerUp->SetPowerUpType(SPRING);
		 testPowerUp->SetImageIndex(5,1);
		 //testPowerUp->SetImageID( m_nImageID[nPowerUpType]);
		 break;
	 }

	if (testPowerUp)
	{
		testPowerUp->SetCurrentTheme(CProfileManager::GetInstance()->GetCurrentTheme());
		testPowerUp->SetImageID( m_nAllIamges);
		testPowerUp->SetHeight(32);
		testPowerUp->SetWidth(32);
		testPowerUp->SetPosX((float)(LevelXPos+nX*testPowerUp->GetWidth()));
		testPowerUp->SetPosY((float)(LevelYPos+nY*testPowerUp->GetHeight()));
		m_pOM->AddObject(testPowerUp);  
		testPowerUp->Release(); 
	}
 }

 void CLevelEngine::CreateTurret(int nTurretType, int nX, int nY)
 {
	 CTurret* testTurret = NULL;

	 switch(nTurretType)
	 {
	 case Turret_Left:
		 testTurret = (CTurret*)m_pFactory->CreateObject("CTurret");
		 testTurret->SetTurretType(FIREL);
		 testTurret->SetImageIndex(6,2);
		 break;
	 case Turret_Down:
		 testTurret = (CTurret*)m_pFactory->CreateObject("CTurret");
		 testTurret->SetTurretType(FIRED);
		 testTurret->SetImageIndex(7,2);
		 break;
	 case Turret_Right:
		 testTurret = (CTurret*)m_pFactory->CreateObject("CTurret");
		 testTurret->SetTurretType(FIRER);
		 testTurret->SetImageIndex(5,2);
		 break;
	 case Turret_Up:
		 testTurret = (CTurret*)m_pFactory->CreateObject("CTurret");
		 testTurret->SetTurretType(FIREU);
		 testTurret->SetImageIndex(4,2);
		 break;
	 case Turret_Target:
		 testTurret = (CTurret*)m_pFactory->CreateObject("CTurret");
		 testTurret->SetTurretType(TARGETTING);
		 testTurret->SetImageIndex(3,2);
		 testTurret->SetShootTimer(3);
		 break;
	 }
	 if(testTurret)
	 {
		 testTurret->SetCurrentTheme(CProfileManager::GetInstance()->GetCurrentTheme());
		 testTurret->SetImageID( m_nAllIamges );
		 testTurret->SetHeight(32);
		 testTurret->SetWidth(32);
		 testTurret->SetPosX((float)(LevelXPos+nX*testTurret->GetWidth()));
		 testTurret->SetPosY((float)(LevelYPos+nY*testTurret->GetHeight()));
		 m_pOM->AddObject(testTurret);  
		 testTurret->Release();
	 }
 }

 void CLevelEngine::CreateBlock(int nBlockType,int nX, int nY)
 {
	CBlock * testBlock = NULL;
	

	switch(nBlockType)
	{
	case Block_Static:
		testBlock = (CBlock*)m_pFactory->CreateObject("CBlock");
		testBlock->SetBlockType(STATIONARY);
		testBlock->SetHeight(32);
		testBlock->SetWidth(32);
		testBlock->SetImageIndex(3,0);
		//testBlock->SetImageID( m_nImageID[nBlockType]);
		break;
	case Block_All:
		testBlock = (CBlock*)m_pFactory->CreateObject("CBlock");
		testBlock->SetBlockType(ALL);
		testBlock->SetHeight(32);
		testBlock->SetWidth(32);
		//testBlock->SetImageID( m_nImageID[nBlockType]);
		testBlock->SetImageIndex(8,0);
		testBlock->SetWeight(120);
		break;
	case Block_Vertical:
		testBlock = (CBlock*)m_pFactory->CreateObject("CBlock");
		testBlock->SetBlockType(VERTICAL);
		testBlock->SetHeight(32);
		testBlock->SetWidth(32);
		testBlock->SetWeight(120);
		testBlock->SetImageIndex(4,0);
		//testBlock->SetImageID( m_nImageID[nBlockType]);
		break;
	case Block_Horizontal:
		testBlock = (CBlock*)m_pFactory->CreateObject("CBlock");
		testBlock->SetBlockType(HORIZONTAL);
		testBlock->SetHeight(32);
		testBlock->SetWidth(32);
		//testBlock->SetImageID( m_nImageID[nBlockType]);
		testBlock->SetImageIndex(5,0);
		testBlock->SetWeight(120);
		break;
	case SpikeUp:
		testBlock = (CBlock*)m_pFactory->CreateObject("CBlock");
		testBlock->SetBlockType(SPIKEUP);
		testBlock->SetHeight(32);
		testBlock->SetWidth(32);
		testBlock->SetImageIndex(9,0);
		//testBlock->SetImageID( m_nImageID[nBlockType]);; 
		break;
	case SpikeDown:
		testBlock = (CBlock*)m_pFactory->CreateObject("CBlock");
		testBlock->SetBlockType(SPIKEDOWN);
		testBlock->SetHeight(32);
		testBlock->SetWidth(32);
		testBlock->SetImageIndex(12,0);
		//testBlock->SetImageID( m_nImageID[nBlockType]); 
		break;
	case SpikeLeft:
		testBlock = (CBlock*)m_pFactory->CreateObject("CBlock");
		testBlock->SetBlockType(SPIKELEFT);
		testBlock->SetHeight(32);
		testBlock->SetWidth(32);
		testBlock->SetImageIndex(11,0);
		//testBlock->SetImageID( m_nImageID[nBlockType]);
		break;
	case SpikeRight:
		testBlock = (CBlock*)m_pFactory->CreateObject("CBlock");
		testBlock->SetBlockType(SPIKERIGHT);
		testBlock->SetHeight(32);
		testBlock->SetWidth(32);
		testBlock->SetImageIndex(10,0);
		//testBlock->SetImageID( m_nImageID[nBlockType]);
		break;
	case Block_HorizontalAuto:
		testBlock = (CBlock*)m_pFactory->CreateObject("CBlock");
		testBlock->SetBlockType(AUTOHOR);
		testBlock->SetHeight(32);
		testBlock->SetWidth(32);
		//testBlock->SetImageID( m_nImageID[nBlockType]);
		testBlock->SetImageIndex(6,0);
		testBlock->SetWeight(120);
		break;
	case Block_VerticalAuto:
		testBlock = (CBlock*)m_pFactory->CreateObject("CBlock");
		testBlock->SetBlockType(AUTOVER);
		testBlock->SetHeight(32);
		testBlock->SetWidth(32);
		//testBlock->SetImageID( m_nImageID[nBlockType]);
		testBlock->SetImageIndex(7,0);
		testBlock->SetWeight(120);
		break;
	case Door_Yellow:
		testBlock = (CBlock*)m_pFactory->CreateObject("CBlock");
		testBlock->SetBlockType(DOOR);
		testBlock->SetHeight(32);
		testBlock->SetWidth(32);
		testBlock->SetImageIndex(0,1);
		//testBlock->SetImageID( m_nImageID[nBlockType]);
		break;
	case Key_Yellow:
		testBlock = (CBlock*)m_pFactory->CreateObject("CBlock");
		testBlock->SetBlockType(KEY);
		testBlock->SetHeight(32);
		testBlock->SetWidth(32);
		testBlock->SetImageIndex(4,1);
		//testBlock->SetImageID( m_nImageID[nBlockType]);
		break;
	case Exit:
		testBlock = (CBlock*)m_pFactory->CreateObject("CBlock");
		testBlock->SetBlockType(EXIT);
		testBlock->SetHeight(32);
		testBlock->SetWidth(32);
		testBlock->SetImageIndex(2,0);
		//testBlock->SetImageID( m_nImageID[nBlockType]);
		break;
	case Start:
		testBlock = (CBlock*)m_pFactory->CreateObject("CBlock");
		testBlock->SetBlockType(START);
		//testBlock->SetImageID(m_nImageID[nBlockType]);
		testBlock->SetHeight(32);
		testBlock->SetWidth(32);
		testBlock->SetPosX((float)(LevelXPos+nX*testBlock->GetWidth()));
		testBlock->SetPosY((float)(LevelYPos+nY*testBlock->GetHeight()));
		testBlock->SetImageIndex(1,0);
		m_cSpawnPoint = testBlock;
		//CGamePlayState::GetInstance()->SetPlayerSpawnX(LevelXPos+nX*32);
		//CGamePlayState::GetInstance()->SetPlayerSpawnY(LevelYPos+nY*32);	
		break;
	}

	if (testBlock)
	{
		testBlock->SetCurrentTheme(CProfileManager::GetInstance()->GetCurrentTheme());
		testBlock->SetImageID(m_nAllIamges);
		testBlock->SetPosX((float)(LevelXPos+nX*testBlock->GetWidth()));
		testBlock->SetPosY((float)(LevelYPos+nY*testBlock->GetHeight()));
		m_pOM->AddObject(testBlock);  
		testBlock->Release(); 
	}

 }